/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.common.constant.evaluation;

import cn.ac.nercis.pes.common.constant.project.SystemState;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 测评功能模块
 *
 * @author zpy
 * @version 1.0.0
 */
public enum EvaluationModule {
    /**被测系统信息**/
    EVALUATION_INF_SYSTEM("被测系统信息", SystemState.PREPARE),
    EVALUATION_BASIS("测评依据",SystemState.PREPARE),
    COURSE("测评过程信息", SystemState.PREPARE),
    COURSE_PROCESS("测评过程", SystemState.PREPARE),
    COURSE_MEMBER("测评项目组成员", SystemState.PREPARE),
    BUSINESS("承载的业务情况", SystemState.PREPARE),
    NETWORK_TOPOLOGY("网络拓扑图及描述", SystemState.PREPARE),
    PASSWORD_USE("密码应用情况", SystemState.PREPARE),
    SYSTEM_ASSET("系统资产", SystemState.PREPARE),
    ASSET_PHY_ENV("物理环境", SystemState.PREPARE),
    ASSET_PHY_SECURITY("物理安防设施", SystemState.PREPARE),
    ASSET_PWD_PRODUCT("密码产品", SystemState.PREPARE),
    ASSET_SERVER_STORAGE("服务器/存储设备", SystemState.PREPARE),
    ASSET_NETWORK_SECURITY("网络及安全设备", SystemState.PREPARE),
    ASSET_DATABASE("数据库管理系统", SystemState.PREPARE),
    ASSET_KEY_BUSINESS("关键业务应用", SystemState.PREPARE),
    ASSET_KEY_DATA("重要数据", SystemState.PREPARE),
    ASSET_COMMUNICATION_CHANNEL("通信信道", SystemState.PREPARE),
    ASSET_SECURITY_DOC("安全管理文档", SystemState.PREPARE),
    ASSET_PERSONNEL("人员", SystemState.PREPARE),
    PASSWORD_SERVICE("密码服务", SystemState.PREPARE),
    SECURITY_THREAT("安全威胁", SystemState.PREPARE),
    LAST_EVALUATION("前次测评情况", SystemState.PREPARE),
    METHOD_TOOL("测评方法及工具", SystemState.PREPARE),
    METHOD_TOOL_TOOLS("测评工具", SystemState.PREPARE),
    METHOD_TOOL_POINT("测评工具检查点", SystemState.PREPARE),

    TARGET_CONFIRM_PHY_ENV("测评指标确认/物理和环境安全", SystemState.PLANNING),
    TARGET_CONFIRM_NET_COMMUNICATION("测评指标确认/网络和通信安全", SystemState.PLANNING),
    TARGET_CONFIRM_DEVICE_COMPUTE("测评指标确认/设备和计算安全", SystemState.PLANNING),
    TARGET_CONFIRM_APP_DATA("测评指标确认/应用和数据安全", SystemState.PLANNING),
    TARGET_CONFIRM_MANAGE_SYSTEM("测评指标确认/管理制度", SystemState.PLANNING),
    TARGET_CONFIRM_PERSONNEL_MANAGE("测评指标确认/人员管理", SystemState.PLANNING),
    TARGET_CONFIRM_BUILD_RUNNING("测评指标确认/建设运行", SystemState.PLANNING),
    TARGET_CONFIRM_EMERGENCY_HANDLING("测评指标确认/应急处置", SystemState.PLANNING),

    CONTENT_CONFIRM_PHY_ENV("测评内容确认/物理和环境安全", SystemState.PLANNING),
    CONTENT_CONFIRM_NET_COMMUNICATION("测评内容确认/网络和通信安全", SystemState.PLANNING),
    CONTENT_CONFIRM_DEVICE_COMPUTE("测评内容确认/设备和计算安全", SystemState.PLANNING),
    CONTENT_CONFIRM_APP_DATA("测评内容确认/应用和数据安全", SystemState.PLANNING),
    CONTENT_CONFIRM_MANAGE("测评内容确认/安全管理", SystemState.PLANNING),

    EVA_REQUIRE_PHY_ENV("测评配置需求/物理和环境安全", SystemState.PLANNING),
    EVA_REQUIRE_NET_COMMUNICATION("测评配置需求/网络和通信安全", SystemState.PLANNING),
    EVA_REQUIRE_DEVICE_COMPUTE("测评配置需求/设备和计算安全", SystemState.PLANNING),
    EVA_REQUIRE_APP_DATA("测评配置需求/应用和数据安全", SystemState.PLANNING),
    EVA_REQUIRE_MANAGE_SYSTEM("测评配置需求/管理制度", SystemState.PLANNING),
    EVA_REQUIRE_PERSONNEL_MANAGE("测评配置需求/人员管理", SystemState.PLANNING),
    EVA_REQUIRE_BUILD_RUNNING("测评配置需求/建设运行", SystemState.PLANNING),
    EVA_REQUIRE_EMERGENCY_HANDLING("测评配置需求/应急处置", SystemState.PLANNING),

    SCENE_PHY_ENV("现场测评/物理和环境安全", SystemState.EVALUATION),
    SCENE_NET_COMMUNICATION("现场测评/网络和通信安全", SystemState.EVALUATION),
    SCENE_DEVICE_COMPUTE("现场测评/设备和计算安全", SystemState.EVALUATION),
    SCENE_APP_DATA("现场测评/应用和数据安全", SystemState.EVALUATION),
    SCENE_MANAGE("现场测评/安全管理", SystemState.EVALUATION),

    UNIT_EVAL_PHY_ENV("单元测评/物理和环境安全", SystemState.REPORT),
    UNIT_EVAL_NET_COMMUNICATION("单元测评/网络和通信安全", SystemState.REPORT),
    UNIT_EVAL_DEVICE_COMPUTE("单元测评/设备和计算安全", SystemState.REPORT),
    UNIT_EVAL_APP_DATA("单元测评/应用和数据安全", SystemState.REPORT),
    UNIT_EVAL_MANAGE_SYSTEM("单元测评/管理制度", SystemState.REPORT),
    UNIT_EVAL_PERSONNEL_MANAGE("单元测评/人员管理", SystemState.REPORT),
    UNIT_EVAL_BUILD_RUNNING("单元测评/建设运行", SystemState.REPORT),
    UNIT_EVAL_EMERGENCY_HANDLING("单元测评/应急处置", SystemState.REPORT),

    OVERALL_EVAL_PHY_ENV("整体测评/物理和环境安全", SystemState.REPORT),
    OVERALL_EVAL_NET_COMMUNICATION("整体测评/网络和通信安全", SystemState.REPORT),
    OVERALL_EVAL_DEVICE_COMPUTE("整体测评/设备和计算安全", SystemState.REPORT),
    OVERALL_EVAL_APP_DATA("整体测评/应用和数据安全", SystemState.REPORT),
    OVERALL_EVAL_MANAGE_SYSTEM("整体测评/管理制度", SystemState.REPORT),
    OVERALL_EVAL_PERSONNEL_MANAGE("整体测评/人员管理", SystemState.REPORT),
    OVERALL_EVAL_BUILD_RUNNING("整体测评/建设运行", SystemState.REPORT),
    OVERALL_EVAL_EMERGENCY_HANDLING("整体测评/应急处置", SystemState.REPORT),

    RISK_ANALYSIS_PHY_ENV("风险分析/物理和环境安全", SystemState.REPORT),
    RISK_ANALYSIS_NET_COMMUNICATION("风险分析/网络和通信安全", SystemState.REPORT),
    RISK_ANALYSIS_DEVICE_COMPUTE("风险分析/设备和计算安全", SystemState.REPORT),
    RISK_ANALYSIS_APP_DATA("风险分析/应用和数据安全", SystemState.REPORT),
    RISK_ANALYSIS_MANAGE_SYSTEM("风险分析/管理制度", SystemState.REPORT),
    RISK_ANALYSIS_PERSONNEL_MANAGE("风险分析/人员管理", SystemState.REPORT),
    RISK_ANALYSIS_BUILD_RUNNING("风险分析/建设运行", SystemState.REPORT),
    RISK_ANALYSIS_EMERGENCY_HANDLING("风险分析/应急处置", SystemState.REPORT),

    OVERALL_APPRAISE_PHY_ENV("总体评价/物理和环境安全", SystemState.REPORT),
    OVERALL_APPRAISE_NET_COMMUNICATION("总体评价/网络和通信安全", SystemState.REPORT),
    OVERALL_APPRAISE_DEVICE_COMPUTE("总体评价/设备和计算安全", SystemState.REPORT),
    OVERALL_APPRAISE_APP_DATA("总体评价/应用和数据安全", SystemState.REPORT),
    OVERALL_APPRAISE_MANAGE_SYSTEM("总体评价/管理制度", SystemState.REPORT),
    OVERALL_APPRAISE_PERSONNEL_MANAGE("总体评价/人员管理", SystemState.REPORT),
    OVERALL_APPRAISE_BUILD_RUNNING("总体评价/建设运行", SystemState.REPORT),
    OVERALL_APPRAISE_EMERGENCY_HANDLING("总体评价/应急处置", SystemState.REPORT),

    PROOF_DELEGATE("密评委托证明",SystemState.PROOF),
    PROOF_ACTIVITY("密评活动证明",SystemState.PROOF),
    PROOF_QUALITY("密评活动质量文件",SystemState.PROOF),
    PROOF_PERSON("密评人员资格证明",SystemState.PROOF),
    PROOF_GRADING("系统定级匹配证明",SystemState.PROOF);

    private final String name;
    private final SystemState state;

    EvaluationModule(String name, SystemState state) {
        this.name = name;
        this.state = state;
    }

    public String getName() {
        return this.name;
    }

    public static List<EvaluationModule> findTargetConfirmModules() {
        return findModules("测评指标确认/");
    }

    public static List<EvaluationModule> findPrepareModules() {
        return Arrays.asList(EVALUATION_INF_SYSTEM,EVALUATION_BASIS,COURSE, BUSINESS, NETWORK_TOPOLOGY, PASSWORD_USE, SYSTEM_ASSET,
                PASSWORD_SERVICE, SECURITY_THREAT, LAST_EVALUATION, METHOD_TOOL);
    }

    public static List<EvaluationModule> findCourseModules(){
        return Arrays.asList(COURSE_PROCESS,COURSE_MEMBER);
    }

    public static List<EvaluationModule> findSystemAssetModules() {
        return Arrays.asList(ASSET_PHY_ENV, ASSET_PHY_SECURITY, ASSET_PWD_PRODUCT, ASSET_SERVER_STORAGE,
                ASSET_NETWORK_SECURITY, ASSET_DATABASE, ASSET_KEY_BUSINESS, ASSET_KEY_DATA, ASSET_COMMUNICATION_CHANNEL,
                ASSET_SECURITY_DOC, ASSET_PERSONNEL);
    }

    public static List<EvaluationModule> findMethodToolModules(){
        return Arrays.asList(METHOD_TOOL_TOOLS,METHOD_TOOL_POINT);
    }


    public static List<EvaluationModule> findContentConfirmModules() {
        return findModules("测评内容确认/");
    }

    public static List<EvaluationModule> findEvaRequireModules() {
        return findModules("测评配置需求/");
    }

    public static List<EvaluationModule> findSceneModules() {
        return findModules("现场测评/");
    }

    public static List<EvaluationModule> findUnitEvalModules() {
        return findModules("单元测评/");
    }

    public static List<EvaluationModule> findOverallEvalModules() {
        return findModules("整体测评/");
    }

    public static List<EvaluationModule> findRiskAnalysisEvalModules() {
        return findModules("风险分析/");
    }

    public static List<EvaluationModule> findOverallAppraiseEvalModules() {
        return findModules("总体评价/");
    }

    public static List<EvaluationModule> findProofEvalModules(){
        return Arrays.asList(PROOF_DELEGATE, PROOF_ACTIVITY, PROOF_QUALITY, PROOF_PERSON, PROOF_GRADING);
    }

    private static List<EvaluationModule> findModules(String name) {
        return Stream.of(EvaluationModule.values())
                .filter(m -> StringUtils.contains(m.name, name))
                .collect(Collectors.toList());
    }

    public static EvaluationModule fromName(String name) {
        EvaluationModule data = COURSE;
        for (EvaluationModule tt : EvaluationModule.values()) {
            if (StringUtils.equals(tt.name, name)) {
                data = tt;
                break;
            }
        }
        return data;
    }

    public static EvaluationModule fromNameByPrepare(String name){
        return Stream.of(findPrepareModules(),findCourseModules(),findSystemAssetModules(),findMethodToolModules())
                .flatMap(Collection::stream)
                .filter(m -> StringUtils.equals(m.name,name))
                .findFirst()
                .orElse(null);
    }

    public static EvaluationModule fromNameBySystemAsset(String name){
        return findSystemAssetModules().stream()
                .filter(m -> StringUtils.equals(m.name,name))
                .findFirst()
                .orElse(null);
    }

    public static EvaluationModule fromNameByTargetConfirm(String layerName) {
        return findTargetConfirmModules().stream()
                .filter(m -> StringUtils.contains(m.name, layerName))
                .findFirst()
                .orElse(EvaluationModule.TARGET_CONFIRM_PHY_ENV);
    }

    public static EvaluationModule fromNameByContentConfirm(String acName) {
        return findContentConfirmModules().stream()
                .filter(m -> StringUtils.contains(m.name, acName))
                .findFirst()
                .orElse(EvaluationModule.CONTENT_CONFIRM_PHY_ENV);
    }

    public static EvaluationModule fromNameByEvaRequire(String layerName) {
        return findEvaRequireModules().stream()
                .filter(m -> StringUtils.contains(m.name, layerName))
                .findFirst()
                .orElse(EvaluationModule.EVA_REQUIRE_PHY_ENV);
    }

    public static EvaluationModule fromNameByScene(String acName) {
        return findSceneModules().stream()
                .filter(m -> StringUtils.contains(m.name, acName))
                .findFirst()
                .orElse(EvaluationModule.SCENE_PHY_ENV);
    }

    public static EvaluationModule fromNameByUnitEval(String layerName) {
        return findUnitEvalModules().stream()
                .filter(m -> StringUtils.contains(m.name, layerName))
                .findFirst()
                .orElse(EvaluationModule.UNIT_EVAL_PHY_ENV);
    }

    public static EvaluationModule fromNameByOverallEval(String layerName) {
        return findOverallEvalModules().stream()
                .filter(m -> StringUtils.contains(m.name, layerName))
                .findFirst()
                .orElse(EvaluationModule.OVERALL_EVAL_PHY_ENV);
    }

    public static EvaluationModule fromNameByRiskAnalysis(String layerName) {
        return findRiskAnalysisEvalModules().stream()
                .filter(m -> StringUtils.contains(m.name, layerName))
                .findFirst()
                .orElse(EvaluationModule.RISK_ANALYSIS_PHY_ENV);
    }

    public static EvaluationModule fromNameByOverallAppraise(String layerName) {
        return findOverallAppraiseEvalModules().stream()
                .filter(m -> StringUtils.contains(m.name, layerName))
                .findFirst()
                .orElse(EvaluationModule.OVERALL_APPRAISE_PHY_ENV);
    }

    public static EvaluationModule fromNameByProof(String name) {
        EvaluationModule data = COURSE;
        for (EvaluationModule tt : findProofEvalModules()) {
            if (StringUtils.equals(tt.name, name)) {
                data = tt;
                break;
            }
        }
        return data;
    }

    public SystemState getState() {
        return state;
    }
}